package com.mhkj.check.service.impl;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.mhkj.base.functionOffice.entity.FunctionOffice;
import com.mhkj.check.repository.PlanCheckRepository;
import com.mhkj.check.service.PlanCheckService;
import com.mhkj.common.enums.PlanType;
import com.mhkj.common.util.ItemHelper;
import com.mhkj.revise.keyPlan.repository.KeyPlanNodeRepository;
import com.mhkj.revise.plan.entity.PlanNode;
import com.mics.core.common.componet.Pagination;
import com.mics.core.common.exception.ErrorCode;
import com.mics.core.common.exception.ParamException;
import com.mics.core.common.util.DateUtils;
import com.mics.core.system.base.service.impl.BaseServiceImpl;
import com.mics.core.system.organizational.bean.Company;
import com.mics.core.system.organizational.bean.Office;
import com.mics.core.system.organizational.bean.Post;
import com.mics.core.system.organizational.service.OrgService;
import com.mics.core.system.rbac.service.DictionaryService;

/**
 * 计划检查
 * @author mics
 * @date 2018年8月27日
 * @version 1.0
 */
@Service
public class PlanCheckServiceImpl extends BaseServiceImpl<PlanNode> implements PlanCheckService{
	@Resource
	private PlanCheckRepository planCheckRepository;
	@Resource
	private KeyPlanNodeRepository keyPlanNodeRepository;
	@Resource
	private OrgService orgService;
	@Resource
	private ItemHelper itemHelper;
	@Resource
	private DictionaryService dictionaryService;
	@Resource
	public void setPlanCheckRepository(PlanCheckRepository planCheckRepository) {
		super.setBaseRepository(planCheckRepository);
	}
	
	@Override
	public Pagination<PlanNode> checkListByPage(PlanNode planNode,String dateTemp,int type,int pageIndex,int pageSize) {
		Specification<PlanNode> spec = new Specification<PlanNode> () {  
			private static final long serialVersionUID = -786003485941679959L;
			@Override
			public Predicate toPredicate(Root<PlanNode> root, CriteriaQuery<?> query,
					CriteriaBuilder criteriaBuilder) {
              List<Predicate> lstPredicates = new ArrayList<Predicate>();
              Join<Object, Object> plan = root.join("plan",JoinType.LEFT);
              Predicate p=criteriaBuilder.equal(plan.get("state").as(Integer.class),2);
              lstPredicates.add(p);
              Join<Object, Object> planType = plan.join("planType",JoinType.INNER);
              if(type == 1){
                  Predicate p1=criteriaBuilder.equal(planType.get("code").as(String.class), PlanType.KEY_TYPE.getCode());
                  lstPredicates.add(p1);
                  Join<Object, Object> item = plan.join("item",JoinType.LEFT);
                  if(itemHelper.getCurrentUserItems().size() > 0 ){
  					Predicate p3=criteriaBuilder.and(item.in(itemHelper.getCurrentUserItems()));
  		            lstPredicates.add(p3);
                  }else{
  					Predicate p3=criteriaBuilder.and(item.isNull());
  		            lstPredicates.add(p3);
                  }
                  if(planNode!=null && planNode.getPlan() != null && planNode.getPlan().getItem() != null && planNode.getPlan().getItem().getId() != null){
                	  Predicate p3=criteriaBuilder.equal(item.get("id"), planNode.getPlan().getItem().getId());
                      lstPredicates.add(p3);
                  }
              }else if(type == 2){
            	  Join<Object, Object> item = plan.join("item",JoinType.LEFT);
                  if(itemHelper.getCurrentUserItems().size() > 0 ){
  					Predicate p3=criteriaBuilder.and(item.in(itemHelper.getCurrentUserItems()));
  		            lstPredicates.add(p3);
                  }else{
  					Predicate p3=criteriaBuilder.and(item.isNull());
  		            lstPredicates.add(p3);
                  }
            	  Predicate p1=criteriaBuilder.equal(planType.get("code").as(String.class), PlanType.MAIN_TYPE.getCode());
                  lstPredicates.add(p1);
                  if(planNode!=null && planNode.getPlan() != null && planNode.getPlan().getItem() != null && planNode.getPlan().getItem().getId() != null){
                	  Predicate p3=criteriaBuilder.equal(item.get("id"), planNode.getPlan().getItem().getId());
                      lstPredicates.add(p3);
                  }
              }else if(type == 3){
            	  Join<Object, Object> item = plan.join("item",JoinType.LEFT);
                  if(itemHelper.getCurrentUserItems().size() > 0 ){
  					Predicate p3=criteriaBuilder.and(item.in(itemHelper.getCurrentUserItems()));
  		            lstPredicates.add(p3);
                  }else{
  					Predicate p3=criteriaBuilder.and(item.isNull());
  		            lstPredicates.add(p3);
                  }
            	  Predicate p1=criteriaBuilder.equal(planType.get("code").as(String.class), PlanType.PROFESSION_TYPE.getCode());
                  lstPredicates.add(p1);
                  if(planNode!=null && planNode.getPlan() != null && planNode.getPlan().getItem() != null && planNode.getPlan().getItem().getId() != null){
                	  Predicate p3=criteriaBuilder.equal(item.get("id"), planNode.getPlan().getItem().getId());
                      lstPredicates.add(p3);
                  }
              }else if(type == 5){
                  List<FunctionOffice> functionOffices = itemHelper.getCurrentUserFunctionOffices();
                  Predicate pfunction = null;
                  if(itemHelper.getCurrentUserFunctionOffices().size() > 0 ){
                  	  pfunction=plan.get("functionOffice").in(functionOffices);
                  }else{
                  	  pfunction=plan.get("functionOffice").isNull();
                  }
  		          lstPredicates.add(pfunction);
            	  Predicate p1=criteriaBuilder.equal(planType.get("code").as(String.class), PlanType.FUNC_TYPE.getCode());
                  lstPredicates.add(p1);
              }else{
            	  List<FunctionOffice> functionOffices = itemHelper.getCurrentUserFunctionOffices();
                  Predicate pfunction = null;
                  if(itemHelper.getCurrentUserFunctionOffices().size() > 0 ){
                  	  pfunction=plan.get("functionOffice").in(functionOffices);
                  }else{
                  	  pfunction=plan.get("functionOffice").isNull();
                  }
            	  Predicate p2=criteriaBuilder.equal(planType.get("code").as(String.class), PlanType.PROFESSION_TYPE.getCode());
            	  lstPredicates.add(criteriaBuilder.or(pfunction, p2));
              }
              Predicate p4=criteriaBuilder.gt(root.get("overDay").as(Integer.class), 0);
              lstPredicates.add(p4);
              if(StringUtils.hasText(dateTemp)){
            	  try {
            		  Date beginDate = new SimpleDateFormat("yyyy-MM").parse(dateTemp);
            		  Date endDate = DateUtils.addMonth(beginDate, 1);
					  Predicate p5=criteriaBuilder.lessThanOrEqualTo(root.get("beginDate"), endDate);
	            	  Predicate p6=criteriaBuilder.greaterThanOrEqualTo(root.get("endDate"), beginDate);
	                  lstPredicates.add(p5);
	                  lstPredicates.add(p6);
				} catch (ParseException e) {
					throw new ParamException(ErrorCode.PARAM_ERROR, "查询参数错误");
				}
              }
              if(StringUtils.hasText(planNode.getNodeName())){
				  Predicate p7 = criteriaBuilder.like(root.get("nodeName").as(String.class), "%" + planNode.getNodeName() + "%");
                  lstPredicates.add(p7);
              }
              Predicate[] arrayPredicates = new Predicate[lstPredicates.size()];
              return criteriaBuilder.and(lstPredicates.toArray(arrayPredicates));
	        }
		};
		Page<PlanNode> pageT =  keyPlanNodeRepository.findAll(spec, PageRequest.of(pageIndex, pageSize, Sort.Direction.ASC,"id"));
		Pagination<PlanNode> pagination = new Pagination<PlanNode>();
		pagination.setTotal(keyPlanNodeRepository.count(spec));
		List<PlanNode> plans = pageT.getContent();
		for(PlanNode planNode2 : plans){
			Company company = orgService.getCompanyById(planNode2.getCompanyId());
			planNode2.setCompanyName(company.getCompanyname());
			Office cOffice = orgService.officeInfo(planNode2.getOfficeId());
			planNode2.setOfficeName(cOffice.getName());
			Post post = orgService.getRoleInfo(planNode2.getPostId());
			planNode2.setPostName(post.getName());
		}
		pagination.setData(plans);
		return pagination;
	}
}
